package com.firsteapps.mobile.android.puzzle;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import android.app.Application;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.media.MediaPlayer;
import android.util.Log;

import com.firsteapps.mobile.android.puzzle.game.Helper;
import com.firsteapps.mobile.android.puzzle.game.PuzzleInfo;
import com.firsteapps.mobile.android.puzzle.util.Consts;
import com.firsteapps.mobile.android.puzzle.util.FirstRunChecker;
import com.firsteapps.mobile.android.puzzle.util.Utilities;

public class PicturePuzzle extends Application {

	private static final String TAG = "Application";
	private MediaPlayer mPlayer;
	private boolean pausePlaying;
	private boolean isPausePressed;
	private String selectedUserName;
	private int credits;
	private boolean musicSetting = true, soundSetting = false, vibrationSetting = false;
	private String[] puzzles;

	private void initFileSystem() {
		final File tempDir = new File(getFilesDir(), Consts.FOLDER_NAME_TEMP.substring(1));
		if (!tempDir.isDirectory())
			tempDir.mkdirs();

		final File configDir = new File(getFilesDir(), Consts.FOLDER_NAME_CONFIG.substring(1));
		if (!configDir.isDirectory())
			configDir.mkdirs();

		final File initialPuzzlesDir = new File(getFilesDir(), Consts.FOLDER_NAME_INITIAL_PUZZLES.substring(1));
		if (!initialPuzzlesDir.isDirectory())
			initialPuzzlesDir.mkdirs();

		File registeredPuzzles = new File(configDir, Consts.FOLDER_NAME_REGISTERED_PUZZLES.substring(14));
		Helper.createConfigFile(this, registeredPuzzles);
		File highscores = new File(configDir, Consts.FILE_NAME_HIGHSCORES.substring(14));
		Helper.createConfigFile(this, highscores);
		File accountBalance = new File(configDir, Consts.FILE_NAME_ACCOUNT_BALANCE.substring(14));
		createAccountBalance(this, accountBalance, Consts.VERSION_FREE);
	}

	@Override
	public void onCreate() {
		super.onCreate();
		Log.d(TAG, "Application started");
		System.out.println(getClass().getSimpleName());

		initFileSystem();

		File options = new File(getFilesDir() + Consts.FOLDER_NAME_CONFIG, "settings");
		if (options.exists()) {
			String[] optionsArray = Helper.getPuzzleData(this, Consts.FILE_NAME_SETTINGS);
			if (optionsArray != null) {
				setMusicEnabled(optionsArray.length > 0 ? optionsArray[0].equals("true") : true);
				setSoundEnabled(optionsArray.length > 1 ? optionsArray[1].equals("true") : false);
				setVibrationEnabled(optionsArray.length > 2 ? optionsArray[2].equals("true") : false);
			}
		}

		FirstRunChecker checker = Utilities.firstRunChecker(this);
		if (checker.checkFirstRun()) {
			final AssetManager assetManager = getAssets();
			try {
				puzzles = assetManager.list("puzzles");
			} catch (IOException e) {
				Log.e("LOADING INITIAL PUZZLES", e.getMessage());
				e.printStackTrace();
			}

			if (puzzles != null && puzzles.length > 0) {
				Thread loadInitialPuzzles = new Thread(new Runnable() {
					@Override
					public void run() {
						try {
							for (String puzzle : puzzles) {
								Helper.decompress(PicturePuzzle.this, assetManager.open("puzzles/" + puzzle),
										Consts.FOLDER_NAME_INITIAL_PUZZLES, false);
							}
						} catch (IOException e) {
							Log.e("LOADING INITIAL PUZZLES", e.getMessage());
							e.printStackTrace();
						}

						String[] loadedPuzzles = Helper.getPuzzleFiles(PicturePuzzle.this, Consts.FILE_TYPE_INFO,
								Consts.FOLDER_NAME_INITIAL_PUZZLES);

						for (String puzzle : loadedPuzzles) {
							PuzzleInfo info = Helper.loadCreatedPuzzle(PicturePuzzle.this, puzzle);
							String fileName = info.getFile();
							info.setFile(Consts.FOLDER_NAME_INITIAL_PUZZLES + "/"
									+ fileName.substring(fileName.lastIndexOf("/") + 1));

							if (info.getAlternativeImage() != null) {
								String alternativeFileName = info.getFile();
								info.setFile(Consts.FOLDER_NAME_INITIAL_PUZZLES + "/"
										+ alternativeFileName.substring(alternativeFileName.lastIndexOf("/") + 1));
							}

							Helper.saveOngoingPuzzle(PicturePuzzle.this, puzzle, info);
						}
					}
				});
				loadInitialPuzzles.start();
			}
		}
	}

	private void createAccountBalance(Context context, File file, boolean isFree) {

		DataInputStream dis = null;
		DataOutputStream dos = null;
		int currentBalance = 0;
		try {
			if (file.exists()) {
				dis = new DataInputStream(new FileInputStream(file));
				currentBalance = dis.readInt();
			} else {
				dos = new DataOutputStream(new FileOutputStream(file));
				currentBalance = isFree ? 0 : 10;
				dos.writeInt(currentBalance);
			}
		} catch (IOException e) {
			Helper.doMessageDialog(context, context.getPackageName(),
					"Unable to create configuration files.\nTry to restart the Application");
			System.out.println(e.getMessage());
			e.printStackTrace();
			return;
		} finally {
			try {
				if (dis != null)
					dis.close();
				if (dos != null)
					dos.close();
			} catch (IOException e) {
				System.out.println(e.getMessage());
				e.printStackTrace();
				return;
			}
		}
		
		setCredits(currentBalance);
	}

	public String getUserName() {
		return selectedUserName;
	}

	public void setUserName(String selectedUserName) {
		this.selectedUserName = selectedUserName;
	}

	public boolean isMusicEnabled() {
		return musicSetting;
	}

	public void setMusicEnabled(boolean musicSetting) {
		this.musicSetting = musicSetting;
	}

	public boolean isSoundEnabled() {
		return soundSetting;
	}

	public void setSoundEnabled(boolean soundSetting) {
		this.soundSetting = soundSetting;
	}

	public boolean isVibrationEnabled() {
		return vibrationSetting;
	}

	public void setVibrationEnabled(boolean vibrationSetting) {
		this.vibrationSetting = vibrationSetting;
	}

	public void initialisePlayer() {
		if (mPlayer == null) {
			setPausePressed(false);
			mPlayer = new MediaPlayer();
			try {
				AssetFileDescriptor afd = getAssets().openFd("song.mp3");
				mPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
				mPlayer.setLooping(true);
				mPlayer.prepare();
				setPausePlaying(false);
			} catch (Exception e) {
				Log.e(TAG, "error: " + e.getMessage(), e);
			}
		}
	}

	public MediaPlayer getPlayer() {
		return mPlayer;
	}

	public boolean getPausePlaying() {
		return pausePlaying;
	}

	public void setPausePlaying(boolean pausePlaying) {
		this.pausePlaying = pausePlaying;
	}

	public void releasePlayer() {
		if (mPlayer != null) {
			mPlayer.release();
			mPlayer = null;
		}
	}

	public void pausePlayer() {
		if (mPlayer != null && mPlayer.isPlaying())
			mPlayer.pause();
	}

	public void resumePlayer() {
		if (mPlayer != null && !mPlayer.isPlaying()) {
			mPlayer.start();
			setPausePlaying(true);
		}
	}

	public boolean getPausePressed() {
		return isPausePressed;
	}

	public void setPausePressed(boolean isPausePressed) {
		this.isPausePressed = isPausePressed;
	}

	public int getCredits() {
		return credits;
	}

	public void setCredits(int credits) {
		this.credits = credits;
	}
}
